/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-11-06     hehung       the first version
 */
/*
 * 无源蜂鸣器驱动程序，PWM
 * */

#include <rtthread.h>
#include "board.h"
#include "app_beep.h"

/******************************** PWM_DEV_NAME ***********************************/
/*** timer3 pwm *** timer4 pwm *** timer5 pwm *** lpwm0 *** lpwm1 *** lpwm2 ***/
/*** t3pwm *** t4pwm *** t5pwm *** lpwm0 *** lpwm1 *** lpwm2 ***/
/**********************************************************************************/
#define PWM_DEV_NAME        "lpwm2" /* PWM 设备名称 */
#define PWM_DEV_CHANNEL     1 /* PWM 通道 */
#define PWM_PERIOD          (1000000u) // 1000000u

#if 0
#define PWM_BEEP_DEBUG
#endif


#define BEEP_MSG_FINISHED_OPEN_THD      ((uint8_t)5u)

ALIGN(RT_ALIGN_SIZE)
struct rt_device_pwm *pwm_dev; /* PWM 设备句柄 */
rt_uint32_t period, pulse;

static uint8_t BEEP_working_mode = BEEP_NONE;

static void PWM_Thread_Entry(void *para);
static int Pwm_Thread_Init(void);

void Pwm_Init(void)
{
    period = PWM_PERIOD; /* 周期 = 1M/period kHz */
    pulse = 0; /* PWM 脉冲宽度值(0 - period) */
    pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME);
    RT_ASSERT(pwm_dev != RT_NULL);
    /* 设置 PWM 周期和脉冲宽度 */
    rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
    /* 使能设备 */
    rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL);

    Pwm_Thread_Init();
}

void Beep_TurnOn(void)
{
    rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, PWM_PERIOD>>1u);
}

void Beep_TurnOff(void)
{
    rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, 0u);
}

void Beep_SetBeepWorkingMode(uint8_t paraMode)
{
    BEEP_working_mode = paraMode;
}

#ifndef PWM_BEEP_DEBUG
static void PWM_Thread_Entry(void *para)
{
    uint8_t i = 0;
    uint8_t beep_finish_cnt = 0u;

    while(1)
    {
        switch(BEEP_working_mode)
        {
            case BEEP_NONE:
            {

            } break;
            case BEEP_MSG_DOWNLOAF_FINISHED:
            {
                if(beep_finish_cnt<BEEP_MSG_FINISHED_OPEN_THD)
                {
                    beep_finish_cnt ++;
                    rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, PWM_PERIOD>>1u);
                }
                else
                {
                    BEEP_working_mode = BEEP_NONE;
                    rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, 0);
                    beep_finish_cnt = 0u;
                }
            } break;
//            case BEEP_DETECTED_BODY:
//            {
//
//            } break;
        }
        rt_thread_mdelay(100);
    }
}

static int Pwm_Thread_Init(void)
{
    rt_thread_t beep_thread;

    beep_thread = rt_thread_create("Beep_thread",
                                    PWM_Thread_Entry,
                                    RT_NULL,
                                    512,
                                    10,
                                    10);

    if(beep_thread != RT_NULL)
    {
        rt_kprintf("Beep Thread Created Success!\n");
        rt_thread_startup(beep_thread);
    }
    else
    {
        rt_kprintf("Beep Thread Create Failed!\n");
    }

    return 0;
}
#else
static void PWM_Thread_Entry(void *para)
{
    Pwm_Init();
    while(1)
    {
        for (int var = 0; var < period; var += (period/100u))
        {
            rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, var);
            rt_thread_mdelay(1000);
        }
    }
}

int Pwm_Thread_Init(void)
{
    rt_thread_t rtc_thread;

    rtc_thread = rt_thread_init(&pwm_thread,
                                "pwm_thread",
                                PWM_Thread_Entry,
                                RT_NULL,
                                &PWM_Thread_Stack[0],
                                sizeof(PWM_Thread_Stack),
                                10,
                                10);

    if(rtc_thread != RT_NULL)
    {
        rt_kprintf("Beep Thread Created Success!\n");
        rt_thread_startup(&pwm_thread);
    }
    else
    {
        rt_kprintf("Beep Thread Create Failed!\n");
    }

    return 0;
}
#ifdef FINSH_USING_MSH
MSH_CMD_EXPORT(Pwm_Thread_Init, Beep PWM control);
#endif

#endif
